package com.kcyu.egoodsmapbackend.service.impl;

import cn.hutool.core.lang.UUID;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.kcyu.egoodsmapbackend.entity.FileDO;
import com.kcyu.egoodsmapbackend.mapper.FileMapper;
import com.kcyu.egoodsmapbackend.service.FileService;
import com.kcyu.egoodsmapbackend.utils.CosUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * @author yujiancong
 * @description 针对表【file(文件)】的数据库操作Service实现
 * @createDate 2024-01-02 11:50:38
 */
@Service
@Slf4j
public class FileServiceImpl extends ServiceImpl<FileMapper, FileDO>
        implements FileService {


    @Override
    @Transactional
    public FileDO upload(MultipartFile file, String modelCode, String busiKey) throws IOException {
        FileDO fileDO = new FileDO();
        fileDO.setModelCode(modelCode);
        fileDO.setBusiKey(busiKey);
        fileDO.setFileName(file.getOriginalFilename());
        fileDO.setFileSize(file.getSize());


        String filename = file.getOriginalFilename();
        // 获取文件扩展名
        String extensionName = filename.substring(filename.lastIndexOf(".") + 1);
        fileDO.setFileType(extensionName);
        // 除去文件扩展名部分
        String fileNameExcludeType = filename.substring(0, filename.lastIndexOf("."));
        // 获取当前时间年月日时分秒字符串
        Date now = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String formattedDate = sdf.format(now);
        String filePath = "e-book-img/" + fileNameExcludeType + formattedDate + "." + extensionName;
        fileDO.setFilePath(filePath);
        this.save(fileDO);

        // 旧逻辑：将文件存到本地
        //        File dest = new File(filePath);
        //        if (!dest.getParentFile().exists()) {
        //            dest.getParentFile().mkdirs();
        //        }
        //
        //        // 写入本地
        //        InputStream inputStream = null;
        //        try {
        //            inputStream = file.getInputStream();
        //        } catch (IOException e) {
        //            throw new RuntimeException(e);
        //        }
        //        inputStreamToFile(inputStream, dest);

        // 新逻辑：存到COS
        CosUtils.uploadFile(file, fileDO.getFilePath());
        fileDO.setFilePath(CosUtils.getPreviewUrl(fileDO.getFilePath()).toString());

        return fileDO;
    }

    @Override
    public List<FileDO> queryFile(String modelCode, String busiKey) {
        QueryWrapper<FileDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(FileDO::getModelCode, modelCode).eq(FileDO::getBusiKey, busiKey);
        List<FileDO> fileDOS = this.baseMapper.selectList(queryWrapper);
        for (FileDO fileDO : fileDOS) {
            URL previewUrl = CosUtils.getPreviewUrl(fileDO.getFilePath());
            fileDO.setFilePath(previewUrl.toString());
        }
        return fileDOS;
    }

    @Override
    public boolean removeFile(Serializable fileId) {
        FileDO fileDO = this.getById(fileId);
        if (fileDO == null) {
            return false;
        }
        String filePath = fileDO.getFilePath();
        File file = new File(filePath);
        if (file.exists()) {
            file.delete();
        }
        return this.removeById(fileId);
    }

    @Override
    public String uploadAsset(MultipartFile file) {
        FileDO commentAssets;
        try {
            commentAssets = this.upload(file, "COMMENT", UUID.fastUUID().toString(true));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        return commentAssets.getFilePath();
//        long time = new Date().getTime();
//        String filePath = time + file.getOriginalFilename();
//        String fileAllPath = filePathBase + "asset/" + filePath;
//        File dest = new File(fileAllPath);
//        if (!dest.getParentFile().exists()) {
//            dest.getParentFile().mkdirs();
//        }
//
//        // 写入本地
//        InputStream inputStream = null;
//        try {
//            inputStream = file.getInputStream();
//        } catch (IOException e) {
//            throw new RuntimeException(e);
//        }
//        inputStreamToFile(inputStream, dest);
//
//        return filePath;
    }

    @Override
    public void getAssets(String filePath, HttpServletResponse response) throws IOException {
        // 获取腾讯云COS的临时访问URL
        URL previewUrl = CosUtils.getPreviewUrl(filePath);

        // 直接重定向到URL
        response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);
        response.setHeader("Location", previewUrl.toString());

    }

    @Override
    @Transactional
    public Boolean moveFile(String fileId, String targetDir) {
        log.info("fileId = {}, targetDir = {}", fileId, targetDir);
        FileDO file = this.getById(fileId);
        CosUtils.initCosClient();
        Boolean b = CosUtils.moveFile(file.getFilePath(), targetDir);
        if (b) {
            file.setFilePath(targetDir);
            this.updateById(file);
            return true;
        } else {
            return false;
        }
    }

    /**
     * 流写入文件
     *
     * @param inputStream 文件输入流
     * @param file        输出文件
     */
    private static void inputStreamToFile(InputStream inputStream, File file) {
        try {
            OutputStream os = new FileOutputStream(file);
            int bytesRead = 0;
            byte[] buffer = new byte[8192];
            while ((bytesRead = inputStream.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            os.close();
            inputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}




